Arbitrary Cutoffs and Causal Inferences RDD Assumptions
Intro
How can we identify causal effects using observational data?
Some of the ways to conduct causal analysis with observational data, we need to run
differences in differences
regression discontinuity design
RDD
RDD are about arbitrary rules and thresholds determining access to policy programs
subjects are in the program if they have scores above a specific threshold
subject are not in the program if they have scores below a specific threshold
Or the other way around
Running or forcing variable - index that measures eligibility for the program (e.g. scores) Cutoff / cutpoint / threshold - the number that the determines access to the program
RDD
RDD
Student ID
Exam Score
Scholarship Awarded?
First-Year GPA
101
83
No
3.2
102
84
No
3.3
103
85
Yes
3.6
104
86
Yes
3.5
105
87
Yes
3.7
106
84.5
No
3.4
107
85.1
Yes
3.6
RDD
Hypothetical tutoring program
Students take an entrance exam
Those who score 70 or lower get a free tutor for the year
Students then take an exit exam at the end of the year
Sharp RD estimates using local polynomial regression.
Number of Obs. 1000
BW type mserd
Kernel Triangular
VCE method NN
Number of Obs. 238 762
Eff. Number of Obs. 121 184
Order est. (p) 1 1
Order bias (q) 2 2
BW est. (h) 7.616 7.616
BW bias (b) 11.669 11.669
rho (h/b) 0.653 0.653
Unique Obs. 238 762
=============================================================================
Method Coef. Std. Err. z P>|z| [ 95% C.I. ]
=============================================================================
Conventional -9.992 1.708 -5.852 0.000 [-13.339 , -6.646]
Robust - - -4.992 0.000 [-14.244 , -6.212]
=============================================================================
Measuring the Gap
Show the code
library(rdrobust)rdrobust(y = tutoring$exit_exam, x = tutoring$entrance_exam, c =70)
Call: rdrobust
Number of Obs. 1000
BW type mserd
Kernel Triangular
VCE method NN
Number of Obs. 238 762
Eff. Number of Obs. 121 184
Order est. (p) 1 1
Order bias (q) 2 2
BW est. (h) 7.616 7.616
BW bias (b) 11.669 11.669
rho (h/b) 0.653 0.653
Unique Obs. 238 762
Show the code
program_data <- tutoring %>%mutate(entrance_centered = entrance_exam -70)model1 <-lm(exit_exam ~ entrance_centered + tutoring,data = program_data)gap<-round(x$estimate[x$term=="tutoringFALSE"],2)x<-tidy(model1)late<-round(x$estimate[x$term=="tutoringFALSE"],2)const<-round(x$estimate[x$term=="(Intercept)"],2)ggplot(tutoring, aes(x = entrance_exam, y = exit_exam, fill = tutoring_text)) +geom_point(size =3, pch =21, color ="white", alpha =0.4) +geom_vline(xintercept =70, size =2, color ="#FFDC00") +labs(x ="Entrance exam score", y ="Exit exam score") +#guides(fill = "none") +guides(fill =guide_legend(reverse =TRUE)) +geom_smooth(data =filter(tutoring, entrance_exam <=70),method ="lm",color="red",#aes(color = tutoring_text),size =2, show.legend =FALSE) +geom_smooth(data =filter(tutoring, entrance_exam >70),method ="lm", color="black",#aes(color = tutoring_text),size =2, show.legend =FALSE) +scale_fill_manual(values =c("black", "red"), name =NULL) +scale_color_manual(values =c("black", "red")) +theme_bw(base_size =28)+annotate(geom ="segment", x =70, xend =70, y = effect_control, yend = effect_treatment,size =4, color ="red") +annotate(geom ="label", x =75, y = const + (late /2),label =paste("δ=", gap),size=5,color ="red", fill =alpha(c("white"),0.8))+coord_sf(xlim =c(30, 100), ylim =c(40, 90))